﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using MatrixOperations;

namespace MatrixOperations
{
    
   
    public class Matrix
    {
      
	private double[][] m_data;
	private int m_size=2;
	private int iDF = 1;

	public Matrix()
	{
	
	}

	public Matrix(double[][] matrixData, int size)
	{
		m_data = new double[size][];
		m_size = size;
		for (int i = 0; i < size; i++)
		{
			for (int j = 0; j < size; j++)
			{
				m_data[i][j] = matrixData[i][j];

			}
		}
	}

	public Matrix(int size)
	{
		m_data = new double[size][];
		m_size = size;

	}

	public void setValue(int i, int j, double value)
	{
		m_data[i][j] = value;
	}

	public double getValue(int i, int j)
	{
		return m_data[i][j];

	}

	public Matrix add(Matrix other)
	{
		Matrix result = new Matrix(m_size);

		for (int i = 0; i < m_size; i++)
		{
			for (int j = 0; j < m_size; j++)
			{
				result.setValue(i, j, m_data[i][j]
						+ other.m_data[i][j]);
			}
		}

		return result;
	}

	public bool equals(Object otherObject)
	{
		Matrix otherNumber = (Matrix) otherObject;
		for (int i = 0; i < m_size; i++)
		{
			for (int j = 0; j < m_size; j++)
			{
				if (m_data[i][j] != otherNumber.m_data[i][j])
					return false;
			}
		}

		return true;

	}

	public Matrix subtract(Matrix other)
	{
		Matrix result = new Matrix(m_size);

		for (int i = 0; i < m_size; i++)
		{
			for (int j = 0; j < m_size; j++)
			{
				result.setValue(i, j, m_data[i][j]
						- other.m_data[i][j]);
			}
		}

		return result;
	}

	public double Determinant()
	{

		int matrixlength = m_data.Length;

		double det = 1;

		m_data = upperTriangle(m_data);

		for (int i = 0; i < matrixlength; i++)
		{
			det = det * m_data[i][i];
		} // multiply down diagonal

		det = det * iDF;

		return det;
	}


	public double[][] upperTriangle(double[][] m)
	{

		double f1 = 0;
		double temp = 0;
		int tms = m.Length; // get This Matrix Size (could be smaller
					// than
					// global)
		int v = 1;

		iDF = 1;

		for (int col = 0; col < tms - 1; col++)
		{
			for (int row = col + 1; row < tms; row++)
			{
				v = 1;

				while (m[col][col] == 0) // check if 0 in
								// diagonal
				{ // if so switch until not
					if (col + v >= tms) // check if switched
								// all rows
					{
						iDF = 0;
						break;
					}
					else
					{
						for (int c = 0; c < tms; c++)
						{
							temp = m[col][c];
							m[col][c] = m[col + v][c]; // switch
											// rows
							m[col + v][c] = temp;
						}
						v++; // count row switch's
						iDF = iDF * -1; // each switch
								// changes
								// determinant
								// factor
					}
				}

				if (m[col][col] != 0)
				{

					try
					{
						f1 = (-1) * m[row][col]
								/ m[col][col];
						for (int i = col; i < tms; i++)
						{
							m[row][i] = f1
									* m[col][i]
									+ m[row][i];
						}
					}
					catch (Exception e)
					{
						System.Console.WriteLine("Still Here!!!");
					}

				}

			}
		}

		return m; 
	}

	public double[][] multiplyMatrix(double[][] a, double[][] b)
	{

		if (a[0].Length != b.Length)
			throw new Exception(
					"Matrices incompatible for multiplication");
		double [][]matrix = new double[a.Length][b[0].length];
        

		for (int i = 0; i < a.Length; i++)
			for (int j = 0; j < b[i].Length; j++)
				matrix[i][j] = 0;

		// cycle through answer matrix
		for (int i = 0; i < matrix.Length; i++)
		{
			for (int j = 0; j < matrix[i].Length; j++)
			{
				matrix[i][j] = calculateRowColumnProduct(a, i,
						b, j);
				
			}
		}
		return matrix;
	}

	public double calculateRowColumnProduct(double[][] A, int row,
			double[][] B, int col)
	{
		double product = 0;
		for (int i = 0; i < A[row].Length; i++)
			product += A[row][i] * B[i][col];
		return product;
	}
}
       

}


